home *** CD-ROM | disk | FTP | other *** search
- /* TTY input driver */
- #include <stdio.h>
- #include <ctype.h>
- #include <conio.h>
- #include "global.h"
- #include "mbuf.h"
- #include "session.h"
- #include "tty.h"
- #include "socket.h"
-
- #define OFF 0
- #define ON 1
- #define CTLB 02 /* use as F3 in dos but no editing */
- #define CTLK 0x0b /* previous session */
- #define CTLL 0x0c /* next session */
- #define CTLO 0x0f /* previous Cstack */
- #define CTLP 0x10 /* next Cstack */
- #define CTLU 21 /* delete current line in total */
- #define CTLW 23 /* erase last word including preceding space */
- #define CTLZ 26 /* EOF char in dos */
-
- #define DEL 0x7f
- #define CLINELEN 162
-
- static int Lastsize = 1;
- static char Lastline[CLINELEN + 1] = "\n";
-
- static void near
- sets(struct session *sp)
- {
- sp->tsavex = wherex();
- sp->tsavey = wherey();
- window(1,Nrows-1,80,Nrows);
- gotoxy(sp->bsavex,sp->bsavey);
- }
-
- static void near
- resets(struct session *sp)
- {
- sp->bsavex = wherex();
- sp->bsavey = wherey();
- window(1,3,80,Nrows-2);
- gotoxy(sp->tsavex,sp->tsavey);
- }
-
- /* Accept characters from the incoming tty buffer and process them
- * (if in cooked mode) or just pass them directly (if in raw mode).
- *
- * Echoing (if enabled) is direct to the raw terminal. This requires
- * recording (if enabled) of locally typed info to be done by the session
- * itself so that edited output instead of raw input is recorded.
- * Control-W added by g1emm again.... for word delete.
- * Control-B/Function key 3 added by g1emm for line repeat.
- */
- struct mbuf *
- ttydriv(struct session *sp,char c)
- {
- struct mbuf *bp;
- char *cp, *rp;
- int cnt;
-
- switch(sp->ttystate.edit){
- case OFF:
- bp = ambufw(1);
- *bp->data = c;
- bp->cnt = 1;
- #ifndef AMIGA
- if(c != CTLZ && sp->ttystate.echo) {
- #else
- if(sp->ttystate.echo) {
- #endif
- if(sp->split) {
- sets(sp);
- putch(c);
- cputs("_\b");
- resets(sp);
- } else {
- putch(c);
- }
- }
- return bp;
- case ON:
- if(sp->ttystate.line == NULLBUF)
- sp->ttystate.line = ambufw(LINESIZE);
-
- bp = sp->ttystate.line;
- cp = bp->data + bp->cnt;
- /* Perform cooked-mode line editing */
- switch(c) {
- case '\r': /* CR and LF both terminate the line */
- case '\n':
- *cp = (sp->ttystate.crnl) ? '\n' : c;
- if(sp->ttystate.echo) {
- if(sp->split) {
- rp = bp->data;
- while(rp < cp) {
- putch(*rp++);
- }
- if(sp != Trace)
- cputs(Eol);
- else
- if(bp->cnt)
- cputs(Eol);
- sets(sp);
- clrscr();
- cputs("_\b");
- resets(sp);
- } else {
- if (Current != Command)
- cputs(Eol);
- else if (bp->cnt) {
- cputs(Eol);
- Command->flag = PPROMPT;
- }
- }
- }
- bp->cnt++;
- sp->ttystate.line = NULLBUF;
- Lastsize = bp->cnt;
-
- /* Commandstack by DK5DC*/
- if(bp->cnt > 1) {
- memcpy(Lastline, bp->data, Lastsize);
- memcpy(sp->Cs[sp->cont], bp->data, Lastsize);
- *(sp->Cs[sp->cont] + Lastsize) = '\0';
- if (++sp->cont == MAXCS)
- sp->cont = 0;
- }
- /* End Commandstack by Glasi*/
- return bp;
- case '\b': /* Backsp->ttystateace */
- if(bp->cnt > 0){
- bp->cnt--;
- if(sp->ttystate.echo) {
- if(sp->split) {
- sets(sp);
- cputs(" \b\b_\b");
- resets(sp);
- } else {
- cputs("\b \b");
- }
- }
- }
- break;
- case CTLU: /* Line kill */
- if(sp->split) {
- sets(sp);
- clrscr();
- bp->cnt = 0;
- gotoxy(1,1);
- cputs("_\b");
- resets(sp);
- } else {
- while(bp->cnt > 0){
- bp->cnt--;
- if(sp->ttystate.echo)
- cputs("\b \b");
- }
- }
- break;
- case CTLB: /* Use last line to finish current */
- cnt = bp->cnt; /* save count so far */
- if(sp->split)
- sets(sp);
- while(bp->cnt > 0) {
- if(sp->ttystate.echo)
- cputs("\b \b");
- bp->cnt--;
- }
- if(sp->split)
- resets(sp);
- bp->cnt = cnt;
- pstr:
- if(bp->cnt < (Lastsize-1)){
- memcpy(bp->data+bp->cnt, &Lastline[bp->cnt], (Lastsize-1) - bp->cnt);
- bp->cnt = Lastsize-1;
- }
- *(bp->data + bp->cnt) = '\0'; /* make it a string */
- if(sp->ttystate.echo) {
- if(sp->split)
- sets(sp);
- cputs(bp->data);
- clreol();
- if(sp->split) {
- cputs("_\b");
- resets(sp);
- }
- }
- break ;
- case CTLP:
- ++sp->cont;
- if (sp->cont >= MAXCS || sp->Cs[sp->cont][0] == '\0')
- sp->cont = 0;
- docs:
- while(bp->cnt > 0){
- bp->cnt--;
- if(sp->ttystate.echo){
- if(sp->split)
- sets(sp);
- cputs("\b \b");
- if(sp->split)
- resets(sp);
- }
- }
- if (sp->Cs[sp->cont][0] != '\0') {
- strcpy(Lastline,sp->Cs[sp->cont]);
- Lastsize = strlen(Lastline);
- bp->cnt = 0;
- }
- goto pstr;
- case CTLO:
- if (sp->Cs[0][0] != '\0') {
- if (sp->cont > 0)
- --sp->cont;
- else
- sp->cont = MAXCS-1;
-
- while(sp->Cs[sp->cont][0] == '\0')
- --sp->cont;
- }
- goto docs;
- case CTLW: /* erase word */
- cnt = 0 ; /* we haven't seen a printable char yet */
- while(bp->cnt > 0){
- *(bp->data + bp->cnt--) = '\n';
- if(sp->ttystate.echo) {
- if(sp->split) {
- sets(sp);
- cputs(" \b\b_\b");
- resets(sp);
- } else {
- cputs("\b \b");
- }
- }
- if (isspace((int)*(bp->data + bp->cnt))) {
- if (cnt)
- break ;
- } else {
- cnt = 1 ;
- }
- }
- break ;
- default: /* Ordinary character */
- *cp = c;
- bp->cnt++;
-
- /* ^Z apparently hangs the terminal emulators under
- * DoubleDos and Desqview. I REALLY HATE having to patch
- * around other people's bugs like this!!!
- */
- if(bp->cnt < CLINELEN - 4 &&
- #ifndef AMIGA
- c != CTLZ && sp->ttystate.echo) {
- #else
- sp->ttystate.echo) {
- #endif
- if(sp->split) {
- sets(sp);
- putch(c);
- cputs("_\b");
- resets(sp);
- } else
- putch(c);
- } else if(bp->cnt >= CLINELEN - 4) {
- putch('\007'); /* Beep */
- bp->cnt--;
- }
- break;
- }
- break;
- }
- return NULLBUF;
- }
-